using System;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using System.Web.Hosting;
using System.Web.UI.WebControls.WebParts;
using Jaws.Core.Web.Entities.Workspaces;

namespace Jaws.Core.Web.Providers
{
    /// <summary>
    /// 
    /// </summary>
    public class XmlPersonalizationProvider : PersonalizationProvider
    {
        private string _applicationName;

        private string DataStoreFile
        {
            get
            {
                var path = SiteSettings.Instance().DataStoragePath();
                return Path.Combine(path, string.Format("Personalization.xml"));
            }
        }

        /// <summary>
        /// When overridden in a derived class, gets or sets the name of the application configured for the provider.
        /// </summary>
        /// <value></value>
        /// <returns>The application configured for the personalization provider.</returns>
        public override string ApplicationName
        {
            get { return _applicationName; }
            set { _applicationName = value; }
        }

        /// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> on a provider after the provider has already been initialized.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (String.IsNullOrEmpty(name))
            {
                name = "XmlPersonalizationProvider";
            }

            base.Initialize(name, config);

            if (!String.IsNullOrEmpty(config["applicationName"]))
            {
                _applicationName = config["applicationName"];
            }
        }

        /// <summary>
        /// When overridden in a derived class, returns a collection containing zero or more <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationStateInfo"></see>-derived objects based on scope and specific query parameters.
        /// </summary>
        /// <param name="scope">A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationScope"></see> with the personalization information to be queried. This value cannot be null.</param>
        /// <param name="query">A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationStateQuery"></see> containing a query. This value can be null.</param>
        /// <param name="pageIndex">The location where the query starts.</param>
        /// <param name="pageSize">The number of records to return.</param>
        /// <param name="totalRecords">The total number of records available.</param>
        /// <returns>
        /// A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationStateInfoCollection"></see> containing zero or more <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationStateInfo"></see>-derived objects.
        /// </returns>
        public override PersonalizationStateInfoCollection FindState(PersonalizationScope scope,
                                                                     PersonalizationStateQuery query, int pageIndex,
                                                                     int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// When overridden in a derived class, returns the number of rows in the underlying data store that exist within the specified scope.
        /// </summary>
        /// <param name="scope">A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationScope"></see> of the personalization information to be queried. This value cannot be null.</param>
        /// <param name="query">A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationStateQuery"></see> containing a query. This value can be null.</param>
        /// <returns>
        /// The number of rows in the underlying data store that exist for the specified scope parameter.
        /// </returns>
        public override int GetCountOfState(PersonalizationScope scope, PersonalizationStateQuery query)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// When overridden in a derived class, loads raw personalization data from the underlying data store.
        /// </summary>
        /// <param name="webPartManager">The <see cref="T:System.Web.UI.WebControls.WebParts.WebPartManager"></see> managing the personalization data.</param>
        /// <param name="path">The path for personalization information to be used as the retrieval key.</param>
        /// <param name="userName">The user name for personalization information to be used as the retrieval key.</param>
        /// <param name="sharedDataBlob">The returned data for the <see cref="F:System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared"></see> scope.</param>
        /// <param name="userDataBlob">The returned data for the <see cref="F:System.Web.UI.WebControls.WebParts.PersonalizationScope.User"></see> scope.</param>
        protected override void LoadPersonalizationBlobs(WebPartManager webPartManager, string path, string userName,
                                                         ref byte[] sharedDataBlob, ref byte[] userDataBlob)
        {

            path = (HttpContext.Current.Request.QueryString["pageid"] != null) ? string.Format("{0}?pageid={1}", path, HttpContext.Current.Request.QueryString["pageid"]) : path;

            WorkspaceCollection spaces = WorkspaceCollection.Load(DataStoreFile);
            if (spaces != null)
                if (spaces.SharedPersonalizationBlob != null)
                {
                    sharedDataBlob = spaces.SharedPersonalizationBlob;
                }

            if (spaces != null)
            {
                Workspace space = spaces.FindByUserAndPath(userName, path);
                if (space != null && space.PersonalizationBlob != null)
                {
                    userDataBlob = space.PersonalizationBlob;
                }
            }
        }

        /// <summary>
        /// When overridden in a derived class, deletes raw personalization data from the underlying data store.
        /// </summary>
        /// <param name="webPartManager">The <see cref="T:System.Web.UI.WebControls.WebParts.WebPartManager"></see> managing the personalization data.</param>
        /// <param name="path">The path for personalization information to be used as the data store key.</param>
        /// <param name="userName">The user name for personalization information to be used as the data store key.</param>
        protected override void ResetPersonalizationBlob(WebPartManager webPartManager, string path, string userName)
        {
            WorkspaceCollection spaces = WorkspaceCollection.Load(DataStoreFile);
            Workspace space = spaces.FindByUserAndPath(userName, path);

            if (space != null)
            {
                spaces.Remove(space);
                spaces.Save(DataStoreFile);
            }
        }

        /// <summary>
        /// When overridden in a derived class, deletes personalization state from the underlying data store based on the specified parameters.
        /// </summary>
        /// <param name="scope">A <see cref="T:System.Web.UI.WebControls.WebParts.PersonalizationScope"></see> of the personalization information to be reset. This value cannot be null.</param>
        /// <param name="paths">The paths for personalization information to be deleted.</param>
        /// <param name="usernames">The user names for personalization information to be deleted.</param>
        /// <returns>The number of rows deleted.</returns>
        public override int ResetState(PersonalizationScope scope, string[] paths, string[] usernames)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// When overridden in a derived class, deletes Web Parts personalization data from the underlying data store based on the specified parameters.
        /// </summary>
        /// <param name="path">The path of the personalization data to be deleted. This value can be null but cannot be an empty string ("").</param>
        /// <param name="userInactiveSinceDate">The date indicating the last time a Web site user changed personalization data.</param>
        /// <returns>
        /// The number of rows deleted from the underlying data store.
        /// </returns>
        public override int ResetUserState(string path, DateTime userInactiveSinceDate)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// When overridden in a derived class, saves raw personalization data to the underlying data store.
        /// </summary>
        /// <param name="webPartManager">The <see cref="T:System.Web.UI.WebControls.WebParts.WebPartManager"></see> managing the personalization data.</param>
        /// <param name="path">The path for personalization information to be used as the data store key.</param>
        /// <param name="userName">The user name for personalization information to be used as the key.</param>
        /// <param name="dataBlob">The byte array of data to be saved.</param>
        protected override void SavePersonalizationBlob(WebPartManager webPartManager, string path, string userName,
                                                        byte[] dataBlob)
        {
            WorkspaceCollection spaces = WorkspaceCollection.Load(DataStoreFile);

            if (!String.IsNullOrEmpty(userName))
            {
                Workspace space;

                if (spaces == null)
                {
                    spaces = new WorkspaceCollection();
                    space = new Workspace { Path = path, UserName = userName, PersonalizationBlob = dataBlob };
                    spaces.Add(space);
                }
                space = spaces.FindByUserAndPath(userName, path);
                //space.PersonalizationBlob = dataBlob;
            }
            else
            {
                spaces.SharedPersonalizationBlob = dataBlob;
            }

            spaces.Save(DataStoreFile);
        }
    }
}